home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 5: The Fifth Dimension
/
17 Bit - The Fifth Dimension (1995)(17 Bit Software)[!].iso
/
files
/
3728.dms
/
3728.adf
/
XPKDisk
/
magic.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-08
|
6KB
|
235 lines
/*-
* MAGIC.C
*
* The xpkdisk.device code that looks into DOS data structures.
*
* $Id: magic.c,v 1.5 1995/04/08 20:21:52 Rhialto Exp $
* $Log: magic.c,v $
* Revision 1.5 1995/04/08 20:21:52 Rhialto
* Add/correct version strings.
*
* Revision 1.4 1995/04/02 14:58:51 Rhialto
* Change #ifdef into #if.
* Update for DICE 3.0. Lots more casts.
*
* Revision 1.3 1993/11/08 13:11:15 Rhialto
* Add RCS tags.
*
*
* This code is (C) Copyright 1993,1994 by Olaf Seibert. All rights reserved.
* May not be used or copied without a licence.
-*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "xpkdisk.h"
#ifndef LIBRARIES_FILEHANDLER_H
#include <libraries/filehandler.h>
#endif
/*#undef DEBUG /**/
#if DEBUG
# include "syslog.h"
#else
# define debug(x)
#endif
static const char rcsId[] = "$Id: magic.c,v 1.5 1995/04/08 20:21:52 Rhialto Exp $";
extern struct DosLibrary *DOSBase;
int
FileNamesMatch(char *path, char *name)
{
char *s;
if (s = strchr(path, ':'))
path = s + 1;
if (s = strrchr(path, '/'))
path = s + 1;
return !strcmp(path, name);
}
/*
* Try to get the DosEnvec values from the mountlist. This is quite a
* work!
* We must be reasonable sure that the dn_Startup fields both refer
* to a FileSysStarupMsg. They must both be pointers (and not some
* small integral values, as used to distinguish CON and RAW, for
* example).
*/
struct DosEnvec *
IsOurDevicenode(UNIT *unit, struct DeviceNode *dn)
{
struct FileSysStartupMsg *dnmsg;
if (dn->dn_Type != DLT_DEVICE)
return NULL;
#if DEBUG
{
char *s = BADDR(dn->dn_Name);
debug(("%.*s:\n", *s, s + 1));
}
#endif
dnmsg = BADDR(dn->dn_Startup);
debug(("Startup: %x, '%.20s' %d\n", dnmsg,
(char *)BADDR(dnmsg->fssm_Device) + 1,
dnmsg->fssm_Unit ));
if (dnmsg &&
(long)dnmsg > 4*100 &&
dnmsg->fssm_Device &&
FileNamesMatch((char *)BADDR(dnmsg->fssm_Device) + 1, DevName) &&
dnmsg->fssm_Unit == unit->xu_UnitNr
) {
long *dnenv = BADDR(dnmsg->fssm_Environ);
/* actually struct DosEnvec */
debug(("Environ: %x\n", dnenv));
if (dnenv && dnenv[0] >= DE_DOSTYPE) {
debug(("Found our mount information at %lx, %lx!\n", dn, dnenv));
return (struct DosEnvec *)dnenv;
}
}
return NULL;
}
void
MagicInitDevicenode(UNIT *unit)
{
struct RootNode *rn = (struct RootNode *) DOSBase->dl_Root;
struct DosInfo *DosInfo = (struct DosInfo *) BADDR(rn->rn_Info);
struct DeviceNode *dn = BADDR(DosInfo->di_DevInfo);
debug(("traverse_bcpl: %x\n", dn));
while (dn) {
struct DosEnvec *de;
if (de = IsOurDevicenode(unit, dn)) {
unit->xu_NumTracks = de->de_Surfaces * (de->de_HighCyl + 1);
unit->xu_TrackLen = 4 * de->de_SizeBlock * de->de_BlocksPerTrack;
debug(("numtracks %d tracklen %d\n",
unit->xu_NumTracks, unit->xu_TrackLen));
#if 0
/* Hackery: */
debug(("tablesize %d CONTROL=%d\n", de->de_TableSize, DE_CONTROL));
if (de->de_TableSize >= DE_CONTROL) {
debug(("string %x: %.20s\n", de->de_Control, de->de_Control));
}
#endif
return;
}
dn = BADDR(dn->dn_Next);
debug(("traverse_bcpl: next is %x\n", dn));
}
}
#define ON(d,s) ((d) |= (s))
#define OFF(d,s) ((d) &= ~(s))
ulong
Flag(char *opt, char *name, ulong mask, ulong previous)
{
char *match;
if (match = strstr(opt, name)) {
int o = 1;
int l = strlen(name);
debug(("Flag: %s\n", match));
if (match[l] == '=')
o = strtol(match + l + 1, NULL, 0);
if (o)
previous |= mask;
else
previous &= ~mask;
}
return previous;
}
void
ParseOptions(UNIT *unit, char *opt)
{
ulong f;
char *value;
debug(("ParseOptions: %s\n", opt));
if (value = strstr(opt, S_XPKPackMethod "=")) {
#define SZ sizeof(unit->xu_XPKPackMethod)
int len;
value += sizeof(S_XPKPackMethod);
len = strcspn(value, " \t\n,;=");
len = min(len, SZ-1);
debug(("Match "S_XPKPackMethod"='%s', len %d\n", value, len));
strncpy(unit->xu_XPKPackMethod, value, len);
unit->xu_XPKPackMethod[len] = '\0';
debug(("PackMethod now %s\n", unit->xu_XPKPackMethod));
} else
debug(("Don't match "S_XPKPackMethod"=\n"));
if (value = strstr(opt, S_MaxCache "=")) {
unit->xu_MaxCache = strtol(value + sizeof(S_MaxCache), NULL, 0);
debug(("Match "S_MaxCache "='%d'\n", unit->xu_MaxCache));
}
if (value = strstr(opt, S_CacheTimeout "=")) {
unit->xu_CacheTimeout = strtol(value + sizeof(S_CacheTimeout), NULL, 0);
debug(("Match "S_CacheTimeout "='%d'\n", unit->xu_CacheTimeout));
}
f = unit->xu_CacheFlags;
f = Flag(opt, S_CMDUPDATE, CACHEF_CMDUPDATE, f);
f = Flag(opt, S_DELAY, CACHEF_DELAY, f);
f = Flag(opt, S_SAFEWRITE, CACHEF_SAFEWRITE, f);
f = Flag(opt, S_LICENSED, CACHEF_LICENSED, f);
unit->xu_CacheFlags = f;
}
int
ReadConfig(UNIT *unit, char *buf, int sz)
{
BPTR fh;
fh = Open(buf, MODE_OLDFILE);
if (fh) {
int len;
len = Read(fh, buf, sz-1);
Close(fh);
if (len >= 0) {
buf[len] = 0;
ParseOptions(unit, buf);
return 1;
}
}
return 0;
}
/*
* First get the permanent settings, then overwrite with the
* temporary ones.
*/
void
MagicInitFile(UNIT *unit)
{
char buf[128];
sprintf(buf, CONFIGFILE_ARC, unit->xu_UnitNr);
ReadConfig(unit, buf, sizeof(buf));
sprintf(buf, CONFIGFILE, unit->xu_UnitNr);
ReadConfig(unit, buf, sizeof(buf));
}
Prototype void MagicInit(UNIT *unit);
void
MagicInit(UNIT *unit)
{
MagicInitDevicenode(unit);
MagicInitFile(unit);
}